﻿using Hx.ADSyncPlatform.Db;
using Hx.ADSyncPlatform.Entity.Entities;
using Hx.ADSyncPlatform.Infrastructure.Exceptions;
using Hx.ADSyncPlatform.Infrastructure.Expression.Common;
using Hx.ADSyncPlatform.Infrastructure.Page;
using Hx.ADSyncPlatform.InfrastructureSecurity;
using Hx.ADSyncPlatform.Service.Base;
using Microsoft.Extensions.Configuration;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Hx.ADSyncPlatform.Service
{
    public class Plat_SysManagerService : BaseService<Plat_SysManager>
    {


        protected DbSet<Plat_SysManager> Plat_SysManagerDb;
        protected DbSet<Plat_SysRole> Plat_SysRoleDb;
        protected DbSet<Plat_SysManagerRole> Plat_SysManagerRoleDb;

        IConfiguration configuration;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="db"></param>
        public Plat_SysManagerService(DbContext db, IConfiguration configuration) : base(db)
        {
            this.Plat_SysManagerDb = db.DbSet<Plat_SysManager>();
            this.Plat_SysRoleDb = db.DbSet<Plat_SysRole>();
            this.Plat_SysManagerRoleDb = db.DbSet<Plat_SysManagerRole>();
            this.configuration = configuration;

        }


        /// <summary>
        /// 添加平台管理员
        /// </summary>
        /// <param name="plat_SysManager"></param>
        /// <returns></returns>
        public bool AddPlatManagerAndRoles(Plat_SysManager plat_SysManager)
        {
            try
            {
                base.dbClient.Ado.BeginTran();
                //plat_SysManager.Password = Encrypt.AESEncrypt(plat_SysManager.Password);
                Guid managerId = Guid.NewGuid();
                plat_SysManager.UserId = managerId;
                this.Plat_SysManagerDb.Insert(plat_SysManager);

                if (plat_SysManager.RoleIds != null && plat_SysManager.RoleIds.Count > 0)
                {
                    List<Plat_SysManagerRole> plat_SysManagerRoles = new List<Plat_SysManagerRole>();
                    foreach (Guid roleId in plat_SysManager.RoleIds)
                    {
                        Plat_SysManagerRole plat_SysManagerRole = new Plat_SysManagerRole();
                        plat_SysManagerRole.Plat_SysManager_ID = managerId;
                        plat_SysManagerRole.Plat_SysRole_ID = roleId;
                        plat_SysManagerRoles.Add(plat_SysManagerRole);
                    }
                    this.Plat_SysManagerRoleDb.InsertRange(plat_SysManagerRoles);
                }

                base.dbClient.Ado.CommitTran();
                return true;
            }
            catch (Exception ex)
            {
                base.dbClient.Ado.RollbackTran();
                throw ex;
            }

        }

        /// <summary>
        /// 修改平台管理员
        /// </summary>
        /// <param name="plat_SysManager"></param>
        /// <returns></returns>
        public bool UpdatePlatManagerAndRoles(Plat_SysManager plat_SysManager)
        {
            try
            {
                base.dbClient.Ado.BeginTran();

                var manager = this.Plat_SysManagerDb.GetById(plat_SysManager.UserId);

                if (manager == null) throw new BizException("当前用户已不存在");

                this.Plat_SysManagerDb.Update(manager.GetChangedCopy(plat_SysManager));

                //先删除用户-角色关系
                this.Plat_SysManagerRoleDb.Delete(n => n.Plat_SysManager_ID == plat_SysManager.UserId);

                if (plat_SysManager.RoleIds != null && plat_SysManager.RoleIds.Count > 0)
                {
                    List<Plat_SysManagerRole> plat_SysManagerRoles = new List<Plat_SysManagerRole>();
                    foreach (Guid roleId in plat_SysManager.RoleIds)
                    {
                        Plat_SysManagerRole plat_SysManagerRole = new Plat_SysManagerRole();
                        plat_SysManagerRole.Plat_SysManager_ID = plat_SysManager.UserId;
                        plat_SysManagerRole.Plat_SysRole_ID = roleId;
                        plat_SysManagerRoles.Add(plat_SysManagerRole);
                    }
                    this.Plat_SysManagerRoleDb.InsertRange(plat_SysManagerRoles);
                }

                base.dbClient.Ado.CommitTran();
                return true;
            }
            catch (Exception ex)
            {
                base.dbClient.Ado.RollbackTran();
                throw ex;
            }

        }

        /// <summary>
        /// 重置密码为默认密码
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public bool ResetPassword(int userId)
        {
            var manager = this.Plat_SysManagerDb.GetById(userId);
            if (manager == null) throw new BizException("当前用户已不存在");
            string defaultPassword = configuration.GetSection("DefaultPassword").ToString();
            manager.Password = Encrypt.AESEncrypt(defaultPassword);
            return this.Plat_SysManagerDb.Update(manager);

        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="oldPassword"></param>
        /// <param name="newPassword"></param>
        /// <param name="confirmPassword"></param>
        /// <returns></returns>
        public string ChangePassword(int userId, string oldPassword, string newPassword, string confirmPassword)
        {
            var manager = this.Plat_SysManagerDb.GetById(userId);
            if (manager == null) throw new BizException("当前用户已不存在");

            if (newPassword != confirmPassword)
            {
                throw new BizException("确认密码与新密码不一一致！");
            }
            if (Encrypt.AESEncrypt(oldPassword) != manager.Password)
            {
                throw new BizException("原始密码不正确！");
            }
            if (Encrypt.AESEncrypt(newPassword) == manager.Password)
            {
                throw new BizException("新密码不能与旧密码一致！");
            }
            manager.Password = Encrypt.AESEncrypt(newPassword);
            this.Plat_SysManagerDb.Update(manager);
            return manager.Password;
        }


        /// <summary>
        /// 删除用户角色
        /// </summary>
        /// <param name="manageId"></param>
        /// <returns></returns>
        public bool DeletePlatManagerAndRoles(Guid manageId)
        {
            try
            {
                base.dbClient.Ado.BeginTran();

                var manager = this.Plat_SysManagerDb.GetById(manageId);

                if (manager == null) throw new BizException("当前用户已经被他人删除！");

                this.Plat_SysManagerDb.DeleteById(manageId);

                this.Plat_SysManagerRoleDb.Delete(n => n.Plat_SysManager_ID == manageId);

                base.dbClient.Ado.CommitTran();
                return true;
            }
            catch (Exception ex)
            {
                base.dbClient.Ado.RollbackTran();
                throw ex;
            }

        }

        /// <summary>
        /// 获取管理员列表 分页 
        /// </summary>
        /// <param name="pagination"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<PageResult<Plat_SysManager>> GetManagerList(Pagination pagination, Dictionary<string, string> param)
        {
            Expression<Func<Plat_SysManager, bool>> expression = n => true;

            if (param.ContainsKey("userName"))
            {
                expression = expression.And(n => n.UserName.Contains(param["userName"]));
            }

            if (param.ContainsKey("mobile"))
            {
                expression = expression.And(n => n.Mobile.Contains(param["mobile"]));
            }

            if (param.ContainsKey("isEnable"))
            {
                bool isEnable = false;
                if (bool.TryParse(param["isEnable"], out isEnable))
                {
                    expression = expression.And(n => n.IsEnable == isEnable);
                }

            }
            PageResult<Plat_SysManager> sysManagers = await base.QueryPage(expression, pagination.pageNum, pagination.pageSize);

            sysManagers.data.ForEach(async manager =>
            {
                IEnumerable<Plat_SysManagerRole> roles = await Plat_SysManagerRoleDb.GetListAsync(role => role.Plat_SysManager_ID == manager.UserId);
                manager.RoleIds = roles.Select(n => n.Plat_SysRole_ID).ToList();
            });
            return sysManagers;

        }
    }

}
